package com.dede.customdrawable;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.animation.LinearInterpolator;

/**
 * @author hsh
 * @date 2017/12/25 13:54.
 * @doc 圆形揭露动画Drawable
 */
public class CircularRevealDrawable extends Drawable implements
        ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {

    private static final String TAG = "CircularRevealDrawable";

    private final Paint mPaint;

    private int mBgColor;
    private int mAnimColor;

    private float mCenterX;
    private float mCenterY;
    private float mRadius = 0;

    private boolean mAnimIsEnd;
    private ValueAnimator radiusValueAnimator;
    private long mDuration;

    public CircularRevealDrawable(@ColorInt int color) {
        this(color, 400);
    }

    public CircularRevealDrawable(@ColorInt int color, @IntRange(from = 0) long duration) {
        this.mBgColor = color;
        this.mDuration = duration;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    public void play(@ColorInt int animColor, float centerX, float centerY, float startRadius, float endRadius) {
        if (animColor != mBgColor) {
            this.mAnimColor = animColor;
            this.mCenterX = centerX;
            this.mCenterY = centerY;
            if (radiusValueAnimator != null && radiusValueAnimator.isRunning()) {
                radiusValueAnimator.removeUpdateListener(this);
                radiusValueAnimator.removeListener(this);
                radiusValueAnimator.cancel();
            }
            radiusValueAnimator = ValueAnimator.ofFloat(startRadius, endRadius);
            radiusValueAnimator.setDuration(mDuration);
            radiusValueAnimator.setInterpolator(new LinearInterpolator());
            radiusValueAnimator.addUpdateListener(this);
            radiusValueAnimator.addListener(this);
            radiusValueAnimator.start();
        }
    }

    public void play(@ColorInt int animColor, float centerX, float centerY) {
        float radiusWidth = getDistance(getWidth(), centerX);
        float radiusHeight = getDistance(getHeight(), centerY);
        double endRadius = Math.sqrt(Math.pow(radiusHeight, 2) + Math.pow(radiusWidth, 2));// 勾股定理拿到斜边长
        this.play(animColor, centerX, centerY, 0, (float) endRadius);
    }

    @Override
    public void draw(@NonNull Canvas canvas) {
        Rect bounds = getBounds();
        mPaint.setColor(mBgColor);
        canvas.drawRect(bounds, mPaint);
        if (!mAnimIsEnd && mAnimColor != mBgColor) {
            mPaint.setColor(mAnimColor);
            canvas.drawCircle(mCenterX, mCenterY, mRadius, mPaint);
        }
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
    }

    private float getDistance(float max, float i) {
        if (max / 2 > i) {
            return max - i;
        } else {
            return i;
        }
    }

    private int getHeight() {
        return getBounds().height();
    }

    private int getWidth() {
        return getBounds().width();
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSPARENT;
    }


    /* implements ValueAnimator.AnimatorUpdateListener */
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        mRadius = (float) animation.getAnimatedValue();
        invalidateSelf();
    }

    /* implements Animator.AnimatorListener */
    @Override
    public void onAnimationStart(Animator animation) {
        mAnimIsEnd = false;
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        mBgColor = mAnimColor;
        mAnimIsEnd = true;
    }

    @Override
    public void onAnimationCancel(Animator animation) {
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    }
}
